#ifndef PM_CRITERIA_H_INCLUDED
#define PM_CRITERIA_H_INCLUDED

#include <wx/wxsqlite3.h>
#include <wx/log.h>

namespace pm {

/**
 * \class ICriteria
 * 
 * Interface for database access
 */
struct ICriteria
{
	virtual ~ICriteria() {}
	virtual bool query(wxSQLite3Database& db) = 0;
};

/**
 * \class ICriteriaForEach
 */
template <typename T>
struct ICriteriaForEach : public ICriteria
{
	typedef std::list<T> Result;
	
	Result m_result;
	
	virtual bool query(wxSQLite3Database& db)
	{
		try {
			wxSQLite3Statement stmt = prepare(db);
			wxSQLite3ResultSet res = stmt.ExecuteQuery();
			while (res.NextRow()) {
				m_result.push_back( T(res) );
			}
		}
		catch (wxSQLite3Exception& e) {
			wxLogError(wxT("ICriteriaForEach::query() failed : %s"), e.GetMessage().c_str());
			return false;
		}
		return true;
	}
	
	virtual wxSQLite3Statement prepare(wxSQLite3Database& db) = 0;
};

/**
 * \class ICriteriaOne
 */
template <typename T>
struct ICriteriaOne : public ICriteria
{
	T m_result;
	virtual bool query(wxSQLite3Database& db)
	{
		bool ok = false;
		try {
			wxSQLite3Statement stmt = prepare(db);
			wxSQLite3ResultSet res = stmt.ExecuteQuery();
			if (res.NextRow()) {
				m_result = T(res);
			}
		}
		catch (wxSQLite3Exception& e) {
			wxLogError(wxT("ICriteriaForEach::query() failed : %s"), e.GetMessage().c_str());
		}
		return ok;
	}
	
	virtual wxSQLite3Statement prepare(wxSQLite3Database& db) = 0;
};

} // namespace pm
#endif // PM_CRITERIA_H_INCLUDED
